package co.com.colcomercio.util;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import co.com.colcomercio.util.exception.OperacionException;

public class Fechas {

	public static String getFechaActual() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyyMMdd");
		java.util.Date currentTime = new java.util.Date();
		return formatter.format(currentTime);
	}
	
	
	public static String getDateActual() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter

		= new java.text.SimpleDateFormat("yyyyMMdd");
		java.util.Date currentTime = new java.util.Date();
		String date = formatter.format(currentTime);
		
		return Formatos.formatoDate(date);
	}
	
	
	public static String getDateNextYear() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter

		= new java.text.SimpleDateFormat("yyyyMMdd");
		java.util.Date currentTime = new java.util.Date();
		String date = formatter.format(currentTime);
		
		String parte1 = date.substring(0, 4);
		String parte2 = date.substring(4, 8);
		
		int year = Integer.parseInt(parte1);
		year++;
		date = String.valueOf(year) + parte2;
		
		return Formatos.formatoDate(date);
	}
	
	
	public static Timestamp addOneYearToCurrentYear(Timestamp currentTime) {
		
		String date = currentTime.toString();
		
		String parte1 = date.substring(0, 4);
		String parte2 = date.substring(4, date.length());
		
		int year = Integer.parseInt(parte1);
		year++;
		date = String.valueOf(year) + parte2;
		
		return Timestamp.valueOf(date);
	}
	
//	public static void main(String[] args) {
//		System.out.println(getHoraActualMinuto());
//	}
	
	public static String getHoraActual() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("kkmmss");
		java.util.Date currentTime = new java.util.Date();
		return formatter.format(currentTime);
	}

	public static String getHoraActualHora() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("kk");
		java.util.Date currentTime = new java.util.Date();
		return formatter.format(currentTime);
	}

	public static String getHoraActualMinuto() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("mm");
		java.util.Date currentTime = new java.util.Date();
		return formatter.format(currentTime);
	}
	
	public static String getTimeActual() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("kkmmss");
		java.util.Date currentTime = new java.util.Date();
		String time = formatter.format(currentTime);
		
		return Formatos.formatoTime(time);
	}
	
	
	public static String getDateTimeActual() {
		
		return getDateActual() + " " + getTimeActual();
	}
	
	
	public static Timestamp getDateTimeNow() {
		
		return Timestamp.valueOf(getDateActual() + " " + getTimeActual());
	}
	
	
	public static Timestamp getDateTimeNextYear() {
		
		return Timestamp.valueOf(getDateNextYear() + " " + getTimeActual());
	}
	
	
	public static Time getTimeNow() {
		
		return Time.valueOf(getTimeActual().substring(0, 8));
	}
	
	
	public static Time getSQLTimeNow() {
		
		return new Time(Fechas.getTimeNow().getTime());
	}
	
	
	public static java.sql.Date getSQLDateNow() {
		
		return java.sql.Date.valueOf(Fechas.getDateActual());
	}
	
	
	public static java.sql.Date parseDate(String str) {
		
		try {
			if (str.trim().length() < 8) {
				str = "00000000";
			}
			String parte1 = null;
			String parte2 = null;
			String parte3 = null;
			
			parte1 = str.substring(0, 4);
			parte2 = str.substring(4, 6);
			parte3 = str.substring(6, 8);
			
			str = parte1 + "-" + parte2 + "-" + parte3;
		}
		catch (Exception e) {
		}
		
		return java.sql.Date.valueOf(str);
	}
	
	public static java.sql.Date parseDateL(String str) {
		
		try {
			if (str.trim().length() < 8) {
				str = "00000000";
			}
			String parte1 = null;
			String parte2 = null;
			String parte3 = null;
			
			parte1 = str.substring(0, 4);
			parte2 = str.substring(5, 7);
			parte3 = str.substring(8, 10);
			
			str = parte1 + "-" + parte2 + "-" + parte3;
		}
		catch (Exception e) {
		}
		
		return java.sql.Date.valueOf(str);
	}
	
	
	public static int getAnoActual() {
		
		String str = getFechaActual();
		int year = Integer.parseInt(str.substring(0, 4));
		
		return year;
	}
	
	
	public static int calcularEdad(Date fecha) {
		
		int edad = 0;
		
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String dt_nacTmp = formatter.format(fecha);
		
		edad = calcularEdad(dt_nacTmp);
		
		return edad;
	}
	
	public static int calcularEdad(Date fecha_nac, Date fecha) {
		
		int edad = 0;
		
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String dt_nacTmp = formatter.format(fecha_nac);
		String dt_fecha=formatter.format(fecha);
		edad = calcularEdad(dt_nacTmp, dt_fecha);
		
		return edad;
	}
	
	
	public static int calcularEdad(String dt_nacTmp) {
		
		int edad = 0;
		
		if (dt_nacTmp.length() >= 10) {
			int ano_nac = new BigDecimal(dt_nacTmp.substring(0, 4)).intValue();
			int mes_nac = new BigDecimal(dt_nacTmp.substring(5, 7)).intValue();
			int dia_nac = new BigDecimal(dt_nacTmp.substring(8, 10)).intValue();
			
			String dt_actual = Fechas.getFechaActual();
			int ano_act = new BigDecimal(dt_actual.substring(0, 4)).intValue();
			int mes_act = new BigDecimal(dt_actual.substring(4, 6)).intValue();
			int dia_act = new BigDecimal(dt_actual.substring(6, 8)).intValue();
			
			edad = ano_act - ano_nac;
			
			if (mes_act - mes_nac < 0) {
				edad--;
			}
			else if (mes_act - mes_nac == 0) {
				
				if (dia_act - dia_nac < 0) {
					edad--;
				}
			}
		}
		
		return edad;
	}
	
	public static int calcularEdad(String dt_nacTmp, String dt_fecha) {
		
		int edad = 0;
		
		if (dt_nacTmp.length() >= 10) {
			int ano_nac = new BigDecimal(dt_nacTmp.substring(0, 4)).intValue();
			int mes_nac = new BigDecimal(dt_nacTmp.substring(5, 7)).intValue();
			int dia_nac = new BigDecimal(dt_nacTmp.substring(8, 10)).intValue();
			
			int ano_act = new BigDecimal(dt_fecha.substring(0, 4)).intValue();
			int mes_act = new BigDecimal(dt_fecha.substring(4, 6)).intValue();
			int dia_act = new BigDecimal(dt_fecha.substring(6, 8)).intValue();
			
			edad = ano_act - ano_nac;
			
			if (mes_act - mes_nac < 0) {
				edad--;
			}
			else if (mes_act - mes_nac == 0) {
				
				if (dia_act - dia_nac < 0) {
					edad--;
				}
			}
		}
		
		return edad;
	}
	
	
	public static String getHoraActualMinutos() {
		
		
		// Format the current time.
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("kkmm");
		java.util.Date currentTime = new java.util.Date();
		return formatter.format(currentTime);
	}
	
	
	public static int diferenciaFechas(BigDecimal fecIni, BigDecimal fecFin) throws OperacionException {
		try {
			int cant = 0;
			GregorianCalendar cal1 = (GregorianCalendar) Calendar.getInstance();
			GregorianCalendar cal2 = (GregorianCalendar) Calendar.getInstance();
			
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
			
			if (fecIni.doubleValue() > 0 && fecFin.doubleValue() > 0 && fecFin.compareTo(fecIni) > 0) {
				cal1.setTime(df.parse(fecFin.toString()));
				cal2.setTime(df.parse(fecIni.toString()));
				int i = 0;
				while (cal1.getTime().compareTo(cal2.getTime()) != 0) {
					cal2.add(Calendar.DATE, 1);
					i++;
				}
				cant = i;
			}
			
			return cant;
		}
		catch (Exception ex) {
			System.err.println("eror comparar dos fechas: " + ex.getMessage());
			throw new OperacionException(ex.getMessage());
		}
	}
	
	
	public static BigDecimal addMonth_toDate(BigDecimal date, int month) {
		
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
		
		GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
		
		try {
			
			java.util.Date dateInField = df.parse(date.toString());
			
			cal.setTime(dateInField);
			cal.add(Calendar.MONTH, month); // rather than adding 7 days, it
			
		}
		catch (ParseException ex) {
			System.out.println("Error: " + ex.getMessage());
		}
		
		String str = df.format(cal.getTime());
		
		return new BigDecimal(str);
	}
	
	
	
	/**
	 * Método que permite sumar una cantidad de días a una fecha.
	 * 
	 * @param time
	 *            Fecha a modificar
	 * @param amount
	 *            Cantidad de días
	 * @param field
	 *            Campo a cual se le va a sumar lso días, puede ser al día, mes
	 *            o año. Se deben utilizar las constantes de la clase Calendar:
	 *            Calendar.DATE (día), Calendar.MONTH (mes) o Calendar.YEAR
	 *            (año)
	 * @return
	 */
	public static Timestamp addDays_ToDate(Timestamp time, int amount, int field) {
		
		Calendar c = setCalendar(time);
		c.add(field, amount);
		
		return new Timestamp(c.getTimeInMillis());
	}
	
	
	private static Calendar setCalendar(Timestamp time) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTimeInMillis(time.getTime());
		return calendar;
	}
	
	
	public static boolean isDate_enRango(String date, String dateR1, String dateR2) throws OperacionException {
		
		if (date == null) {
			
			throw new OperacionException("La Fecha que se desea comparar es obligatoria.");
		}
		
		if (dateR1 == null) {
			
			throw new OperacionException("La Fecha Inicial del rango es obligatoria.");
		}
		
		if (dateR2 == null) {
			
			throw new OperacionException("La Fecha Final del rango es obligatoria.");
		}
		
		return isDate_enRango(Timestamp.valueOf(date), Timestamp.valueOf(dateR1), Timestamp.valueOf(dateR2));
	}
	
	
	public static boolean isDate_enRango(Timestamp date, Timestamp dateR1, Timestamp dateR2) throws OperacionException {
		
		boolean isDate_correcto = false;
		
		if (date == null) {
			
			throw new OperacionException("La Fecha que se desea comparar es obligatoria.");
		}
		
		if (dateR1 == null) {
			
			throw new OperacionException("La Fecha Inicial del rango es obligatoria.");
		}
		
		if (dateR2 == null) {
			
			throw new OperacionException("La Fecha Final del rango es obligatoria.");
		}
		
		try {
			
			if (date.compareTo(dateR1) >= 0 && date.compareTo(dateR2) <= 0) {
				
				isDate_correcto = true;
			}
		}
		catch (Exception ex) {
			System.err.println("eror comparar dos fechas: " + ex.getMessage());
			throw new OperacionException(ex.getMessage());
		}
		
		return isDate_correcto;
	}
	
	
	public static boolean isRango_Valido(String dateR1, String dateR2) throws OperacionException {
		
		if (dateR1 == null) {
			
			throw new OperacionException("La Fecha Inicial del rango es obligatoria.");
		}
		
		if (dateR2 == null) {
			
			throw new OperacionException("La Fecha Final del rango es obligatoria.");
		}
		
		return isRango_Valido(Timestamp.valueOf(dateR1), Timestamp.valueOf(dateR2));
	}
	
	
	public static boolean isRango_Valido(Timestamp dateR1, Timestamp dateR2) throws OperacionException {
		
		boolean isRango_correcto = false;
		
		if (dateR1 == null) {
			
			throw new OperacionException("La Fecha Inicial del rango es obligatoria.");
		}
		
		if (dateR2 == null) {
			
			throw new OperacionException("La Fecha Final del rango es obligatoria.");
		}
		
		try {
			
			if (dateR1.compareTo(dateR2) <= 0) {
				
				isRango_correcto = true;
			}
		}
		catch (Exception ex) {
			System.err.println("eror comparar dos fechas: " + ex.getMessage());
			throw new OperacionException(ex.getMessage());
		}
		
		return isRango_correcto;
	}
	
	public static boolean masDeUnMesDiff(Date fecha_ini, Date fecha_hasta)
	{
		boolean meses = false;
		
			Calendar calendar1 = new GregorianCalendar();
			calendar1.setTime(fecha_ini);
			
			Calendar calendar2 = new GregorianCalendar();
			calendar2.setTime(fecha_hasta);
						
			if(calendar2.get(Calendar.YEAR) - calendar1.get(Calendar.YEAR) > 0)
			{
				meses = true;
			}
			else if(calendar2.get(Calendar.YEAR) - calendar1.get(Calendar.YEAR) == 0)
			{
				if(calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH) > 1)
					
					meses = true;
				else
				{
					if(calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH) == 0)
					{					
							meses = false;
					}
					else if(calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH) == 1)
					{
						if(calendar2.get(Calendar.DATE) > calendar1.get(Calendar.DATE))
							meses = true;					
					}	
				}
			}
		
		return meses;
	}
	
	public static int diferenciaFechasDate(BigDecimal fecIni, BigDecimal fecFin) throws OperacionException {
		try {
			long cantl = 0;
			int cant = 0;
			Date fecIniDate = Fechas.parseDate(fecIni.toString());
			Date fecFinDate = Fechas.parseDate(fecFin.toString());
			
			cantl = fecFinDate.getTime() - fecIniDate.getTime();
			
			cant = (int)Math.round((cantl/(1000*60*60*24)));
			
			return cant;
		}
		catch (Exception ex) {
			System.err.println("error comparar dos fechas: " + ex.getMessage());
			throw new OperacionException(ex.getMessage());
		}
		
	}

}
